home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
termsorc.lha
/
Extras
/
Source
/
gtlayout-source.lha
/
LTP_TabClass.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-24
|
18KB
|
797 lines
/* GadTools layout toolkit
**
** Copyright © 1993-1995 by Olaf `Olsen' Barthel
** Freely distributable.
**
** :ts=4
*/
#include "gtlayout_global.h"
//#define DB(x) x
#define DB(x) ;
#if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
#define TIA_Labels (TAG_USER+0x90000)
#define TIA_Font (TAG_USER+0x90001)
#define TIA_Screen (TAG_USER+0x90002)
#define TIA_Index (TAG_USER+0x90003)
#define TIA_DrawInfo (TAG_USER+0x90004)
#define TIA_SizeType (TAG_USER+0x90005)
STATIC VOID __regargs
DeleteBitMap(struct BitMap *BitMap,BOOL Chip)
{
if(V39 && !Chip)
FreeBitMap(BitMap);
else
{
if(BitMap)
{
WORD i;
for(i = 0 ; i < BitMap->Depth ; i++)
FreeVec(BitMap->Planes[i]);
FreeVec(BitMap);
}
}
}
STATIC struct BitMap * __regargs
CreateBitMap(UWORD Width,UWORD Height,UBYTE Depth,struct BitMap *Friend,BOOL Chip)
{
struct BitMap *BitMap;
if(V39 && !Chip)
BitMap = AllocBitMap(Width,Height,Depth,NULL,Friend);
else
{
if(BitMap = (struct BitMap *)AllocVec(sizeof(struct BitMap),MEMF_ANY | MEMF_PUBLIC))
{
LONG PageSize;
WORD i;
InitBitMap(BitMap,Depth,Width,Height);
PageSize = BitMap->BytesPerRow * BitMap->Rows;
for(i = 0 ; i < Depth ; i++)
{
if(!(BitMap->Planes[i] = (PLANEPTR)AllocVec(PageSize,MEMF_CHIP)))
{
WORD j;
for(j = 0 ; j < i ; j++)
FreeVec(BitMap->Planes[j]);
FreeVec(BitMap);
return(NULL);
}
}
}
}
return(BitMap);
}
/* // not used
STATIC VOID __regargs
NotifyIndex(struct IClass *class,struct Gadget *gadget,struct GadgetInfo *GInfo,struct opUpdate *msg,LONG Index)
{
struct TagItem Tags[3];
Tags[0].ti_Tag = GA_ID;
Tags[0].ti_Data = gadget->GadgetID;
Tags[1].ti_Tag = TIA_Index;
Tags[1].ti_Data = Index;
Tags[2].ti_Tag = TAG_DONE;
DoSuperMethod(class,(Object *)gadget,OM_NOTIFY,Tags,GInfo,((msg->MethodID == OM_UPDATE) ? (msg->opu_Flags) : 0L));
}
*/
STATIC VOID __regargs
RenderTabs(struct RastPort *RPort,struct Gadget *gadget,TabInfo *Info,UWORD *Pens,UWORD Pull,BOOL Disabled)
{
UWORD Width,Height;
LONG i;
UWORD Pen;
Width = Info->TabWidth;
Height = Info->TabHeight;
SetRast(&Info->RPort,Pens[BACKGROUNDPEN]);
for(i = 0 ; i < 4 ; i++)
{
if(i & 1)
Pen = SHADOWPEN;
else
Pen = SHINEPEN;
SetAPen(&Info->RPort,Pens[Pen]);
Move(&Info->RPort,0,Height - 1 - i);
Draw(&Info->RPort,gadget->Width - 1 - Info->Thick * i,Height - 1 - i);
}
for(i = Info->Count - 1 ; i >= 0 ; i--)
{
if(i != Info->Current)
BltMaskBitMapRastPort(Info->Tabs[i].BitMap,0,0,&Info->RPort,Info->Tabs[i].Left,4,Width,Height - 6,ABC|ABNC|ANBC,Info->Mask);
}
BltMaskBitMapRastPort(Info->Tabs[Info->Current].BitMap,0,0,&Info->RPort,Info->Tabs[Info->Current].Left,0,Width,Height - Pull,ABC|ABNC|ANBC,Info->Mask);
WaitBlit();
BltBitMapRastPort(Info->BitMap,0,0,RPort,gadget->LeftEdge,gadget->TopEdge + gadget->Height - (Info->TabHeight + 2),gadget->Width,Info->TabHeight,0xC0);
/* // Intuition ghosts images all by itself
if(Disabled)
{
SetAPen(RPort,Pens[BLOCKPEN]);
SetDrMd(RPort,JAM1);
SetAfPt(RPort,(UWORD *)&ghostingPat,1);
RectFill(RPort,gadget->LeftEdge,gadget->TopEdge,gadget->LeftEdge + gadget->Width - 1,gadget->TopEdge + gadget->Height - 1);
SetAfPt(RPort,NULL,0);
}
*/
}
STATIC ULONG __regargs
SetMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
struct TagItem *Tag;
BOOL NeedRefresh = FALSE;
BOOL Disabled;
Disabled = gadget->Flags & GFLG_DISABLED;
if(Tag = FindTagItem(GA_Disabled,SetInfo->ops_AttrList))
{
if(Tag->ti_Data && !Disabled || !Tag->ti_Data && Disabled)
{
Disabled = Tag->ti_Data;
NeedRefresh = TRUE;
}
}
if(Tag = FindTagItem(TIA_Index,SetInfo->ops_AttrList))
{
LONG Index = Tag->ti_Data;
if(Index >= Info->Count)
Index = Info->Count - 1;
if(Index != Info->Current)
{
Info->Initial = Info->Current = Index;
NeedRefresh = TRUE;
}
}
if(NeedRefresh)
{
struct RastPort *RPort;
if(RPort = ObtainGIRPort(SetInfo->ops_GInfo))
{
RenderTabs(RPort,gadget,Info,SetInfo->ops_GInfo->gi_DrInfo->dri_Pens,0,Disabled);
/* NotifyIndex(class,gadget,SetInfo->ops_GInfo,(struct opUpdate *)SetInfo,Info->Current);*/
ReleaseGIRPort(RPort);
}
}
return(DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo));
}
STATIC ULONG __regargs
RenderMethod(struct IClass *class,struct Gadget *gadget,struct gpRender *RenderInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
RenderTabs(RenderInfo->gpr_RPort,gadget,Info,RenderInfo->gpr_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
return(TRUE);
}
STATIC ULONG __regargs
DisposeMethod(struct IClass *class,struct Gadget *gadget,Msg msg)
{
TabInfo *Info = INST_DATA(class,gadget);
if(Info->Mask || Info->Tabs || Info->BitMap)
WaitBlit();
if(Info->Mask)
FreeVec(Info->Mask);
if(Info->Tabs)
{
LONG i;
for(i = 0 ; i < Info->Count ; i++)
DeleteBitMap(Info->Tabs[i].BitMap,TRUE);
FreeVec(Info->Tabs);
}
DeleteBitMap(Info->BitMap,FALSE);
return(DoSuperMethodA(class,(Object *)gadget,msg));
}
STATIC ULONG __regargs
NewMethod(struct IClass *class,struct Gadget *gadget,struct opSet *SetInfo)
{
if(gadget = (struct Gadget *)DoSuperMethodA(class,(Object *)gadget,(Msg)SetInfo))
{
TabInfo *Info = INST_DATA(class,gadget);
struct TagItem *Tag,*TagList = SetInfo->ops_AttrList;
struct TextAttr *FontAttr;
UWORD Width,Height;
struct DrawInfo *DrawInfo;
STRPTR *Labels;
struct Screen *Screen;
Width = Height = 0;
FontAttr = NULL;
DrawInfo = NULL;
Labels = NULL;
Screen = NULL;
memset(Info,0,sizeof(TabInfo));
while(Tag = NextTagItem(&TagList))
{
switch(Tag->ti_Tag)
{
case TIA_Labels:
Labels = (STRPTR *)Tag->ti_Data;
break;
case TIA_Screen:
Screen = (struct Screen *)Tag->ti_Data;
break;
case TIA_Font:
FontAttr = (struct TextAttr *)Tag->ti_Data;
break;
case TIA_Index:
Info->Current = Tag->ti_Data;
break;
case TIA_DrawInfo:
DrawInfo = (struct DrawInfo *)Tag->ti_Data;
break;
case GA_Width:
Width = Tag->ti_Data;
break;
case GA_Height:
Height = Tag->ti_Data;
break;
}
}
if(Labels)
{
while(Labels[Info->Count])
Info->Count++;
}
if(Screen && DrawInfo && FontAttr && Width && Height && Labels && Info->Count)
{
struct TextFont *Font;
if(Font = OpenFont(FontAttr))
{
struct RastPort *RPort = &Info->RPort;
InitRastPort(RPort);
SetFont(RPort,Font);
if(Height >= RPort->TxHeight + 11)
{
LONG i,Len,MaxWidth,Remain;
UWORD Lean;
if(Info->Current < 0)
Info->Current = 0;
else
{
if(Info->Current >= Info->Count)
Info->Current = Info->Count - 1;
}
Lean = (TextLength(RPort,"A",1) + 1) / 2;
Info->Thick = DrawInfo->dri_Resolution.Y / DrawInfo->dri_Resolution.X;
// Info->Thick = 2;
if(Info->Thick < 1)
Info->Thick = 1;
for(i = MaxWidth = 0 ; i < Info->Count ; i++)
{
if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
MaxWidth = Len;
}
MaxWidth = 2 + (Lean + Info->Thick - 1 + Info->Thick + MaxWidth + Info->Thick + Lean + Info->Thick - 1) + 2;
Remain = (Width - MaxWidth - 5 * Info->Thick) / (Info->Thick * 4);
if(Remain >= Info->Count - 1)
{
if(Info->Tabs = (TabEntry *)AllocVec(sizeof(TabEntry) * Info->Count,MEMF_ANY|MEMF_CLEAR))
{
STATIC BYTE PenNumbers[] =
{
BACKGROUNDPEN,
SHINEPEN,
SHADOWPEN,
TEXTPEN
};
struct BitMap __aligned Mask;
BOOL GotIt = TRUE;
UWORD Depth;
LONG MaxPen;
UWORD *Pens = DrawInfo->dri_Pens;
for(i = 0, MaxPen = -1 ; i < sizeof(PenNumbers) ; i++)
{
if(Pens[PenNumbers[i]] > MaxPen)
MaxPen = Pens[PenNumbers[i]];
}
for(i = 1 ; i < 9 ; i++)
{
if(MaxPen < (1 << i))
{
Depth = i;
break;
}
}
Info->TabWidth = MaxWidth;
Info->TabHeight = 4 + RPort->TxHeight + 5;
InitBitMap(&Mask,1,Info->TabWidth,Info->TabHeight);
Mask.Planes[1] = NULL;
for(i = 0 ; GotIt && i < 2 ; i++)
{
if(!(Mask.Planes[i] = (PLANEPTR)AllocVec(Mask.BytesPerRow * Mask.Rows,MEMF_CHIP)))
GotIt = FALSE;
}
for(i = 0 ; GotIt && i < Info->Count ; i++)
{
if(!(Info->Tabs[i].BitMap = CreateBitMap(Info->TabWidth,Info->TabHeight,Depth,NULL,TRUE)))
GotIt = FALSE;
}
if(V39)
Depth = GetBitMapAttr(Screen->RastPort.BitMap,BMA_DEPTH);
else
Depth = Screen->RastPort.BitMap->Depth;
if(!(Info->BitMap = CreateBitMap(gadget->Width,Info->TabHeight,Depth,Screen->RastPort.BitMap,FALSE)))
GotIt = FALSE;
if(GotIt)
{
struct TmpRas TmpRas;
LONG j,Len,Offset,Pos;
InitTmpRas(&TmpRas,Mask.Planes[1],RASSIZE(Info->TabWidth,Info->TabHeight));
RPort->TmpRas = &TmpRas;
RPort->BitMap = &Mask;
SetRast(RPort,0);
SetAPen(RPort,1);
SetDrMd(RPort,JAM1);
Move(RPort,0,Info->TabHeight - 1);
Draw(RPort,Lean - 1,0);
Move(RPort,Lean,0);
Draw(RPort,Info->TabWidth - (Lean + 1),0);
Move(RPort,Info->TabWidth - Lean,0);
Draw(RPort,Info->TabWidth - 1,Info->TabHeight - 1);
Move(RPort,0,Info->TabHeight - 1);
Draw(RPort,Info->TabWidth - 1,Info->TabHeight - 1);
Flood(RPort,1,Info->TabWidth / 2,Info->TabHeight / 2);
SetAPen(RPort,0);
for(i = 0 ; i < 4 ; i++)
{
for(j = 0 ; j < 2 ; j++)
WritePixel(RPort,j,Info->TabHeight - 1 - i);
for(j = 0 ; j < 2 ; j++)
WritePixel(RPort,Info->TabWidth - 1 - j,Info->TabHeight - 1 - i);
}
WaitBlit();
FreeVec(Mask.Planes[1]);
RPort->TmpRas = NULL;
Offset = (Width - Info->Thick * 5) / Info->Count;
while(Offset > 0 && Offset * (Info->Count - 1) + Info->TabWidth >= Width - Info->Thick * 5)
Offset--;
if(Offset > Info->TabWidth + Info->Thick)
Offset = Info->TabWidth + Info->Thick;
Pos = 2 * Info->Thick;
for(i = 0 ; i < Info->Count ; i++)
{
RPort->BitMap = Info->Tabs[i].BitMap;
Info->Tabs[i].Left = Pos;
Pos += Offset;
SetRast(RPort,Pens[BACKGROUNDPEN]);
SetAPen(RPort,Pens[SHINEPEN]);
for(j = 0 ; j < Info->Thick ; j++)
{
Move(RPort,2 + j,Info->TabHeight - 1);
Draw(RPort,2 + j + Lean - 1,0);
}
Move(RPort,2 + Lean,0);
Draw(RPort,Info->TabWidth - (Lean + 1) - 2,0);
SetAPen(RPort,Pens[SHADOWPEN]);
for(j = 0 ; j < Info->Thick ; j++)
{
Move(RPort,Info->TabWidth - Lean - j - 2,0);
Draw(RPort,Info->TabWidth - 1 - j - 2,Info->TabHeight - 1);
}
SetAPen(RPort,Pens[TEXTPEN]);
Len = strlen(Labels[i]);
Move(RPort,(Info->TabWidth - TextLength(RPort,Labels[i],Len)) / 2,2 + RPort->TxBaseline);
Text(RPort,Labels[i],Len);
}
Info->Mask = Mask.Planes[0];
Info->Offset = Offset;
Info->RPort.BitMap = Info->BitMap;
CloseFont(Font);
return((ULONG)gadget);
}
}
}
}
CloseFont(Font);
}
}
CoerceMethod(class,(Object *)gadget,OM_DISPOSE);
}
return(0);
}
STATIC ULONG __regargs
InputMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
ULONG Result = GMR_MEACTIVE;
BOOL Done = FALSE;
WORD x,y;
x = InputInfo->gpi_Mouse.X;
y = InputInfo->gpi_Mouse.Y;
if(InputInfo->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
{
if(InputInfo->gpi_IEvent->ie_Code == MENUDOWN)
{
Result = GMR_NOREUSE;
Done = TRUE;
}
else
{
if(InputInfo->gpi_IEvent->ie_Code == SELECTUP)
{
Done = TRUE;
if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
{
Result = GMR_REUSE | GMR_VERIFY;
*InputInfo->gpi_Termination = Info->Current;
}
else
Result = GMR_NOREUSE;
}
}
}
if(Result == GMR_NOREUSE)
{
struct RastPort *RPort;
if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
{
Info->Current = Info->Initial;
RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
/* NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Info->Current);*/
ReleaseGIRPort(RPort);
}
}
if(!Done)
{
if(x >= 0 && x < gadget->Width && y >= 0 && y < gadget->Height)
{
LONG Index,i;
for(Index = -1, i = Info->Count - 1 ; i >= 0 ; i--)
{
if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
Index = i;
}
if(Index != Info->Current && Index != -1)
{
struct RastPort *RPort;
if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
{
Info->Current = Index;
RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,2,gadget->Flags & GFLG_DISABLED);
/* NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Index);*/
ReleaseGIRPort(RPort);
}
}
}
}
return(Result);
}
STATIC ULONG __regargs
ActiveMethod(struct IClass *class,struct Gadget *gadget,struct gpInput *InputInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
struct RastPort *RPort;
if(RPort = ObtainGIRPort(InputInfo->gpi_GInfo))
{
LONG Current,i;
WORD x;
x = InputInfo->gpi_Mouse.X;
for(Current = -1, i = Info->Count - 1 ; i >= 0 ; i--)
{
if(x >= Info->Tabs[i].Left && x < Info->Tabs[i].Left + Info->TabWidth)
Current = i;
}
Info->Initial = Info->Current;
if(Current != Info->Current && Current != -1)
{
Info->Current = Current;
RenderTabs(RPort,gadget,Info,InputInfo->gpi_GInfo->gi_DrInfo->dri_Pens,2,gadget->Flags & GFLG_DISABLED);
}
/* NotifyIndex(class,gadget,InputInfo->gpi_GInfo,(struct opUpdate *)InputInfo,Info->Current);*/
ReleaseGIRPort(RPort);
return(GMR_MEACTIVE);
}
else
return(GMR_NOREUSE);
}
STATIC ULONG __regargs
InactiveMethod(struct IClass *class,struct Gadget *gadget,struct gpGoInactive *InactiveInfo)
{
TabInfo *Info = INST_DATA(class,gadget);
struct RastPort *RPort;
LONG Index;
if(InactiveInfo->gpgi_Abort)
Index = Info->Initial;
else
Index = Info->Current;
if(RPort = ObtainGIRPort(InactiveInfo->gpgi_GInfo))
{
Info->Current = Index;
RenderTabs(RPort,gadget,Info,InactiveInfo->gpgi_GInfo->gi_DrInfo->dri_Pens,0,gadget->Flags & GFLG_DISABLED);
/* NotifyIndex(class,gadget,InactiveInfo->gpgi_GInfo,(struct opUpdate *)InactiveInfo,Info->Current);*/
ReleaseGIRPort(RPort);
}
return(0);
}
BOOL __stdargs
LTP_ObtainTabSize(struct IBox *Box,...)
{
va_list VarArgs;
struct TagItem *TagList,*Tag;
struct TextAttr *FontAttr;
struct DrawInfo *DrawInfo;
STRPTR *Labels;
LONG Count;
LONG SizeType;
BOOL Success;
Success = FALSE;
va_start(VarArgs,Box);
TagList = (struct TagItem *)VarArgs;
SizeType = GDOMAIN_NOMINAL;
FontAttr = NULL;
DrawInfo = NULL;
Labels = NULL;
while(Tag = NextTagItem(&TagList))
{
switch(Tag->ti_Tag)
{
case TIA_Labels:
Labels = (STRPTR *)Tag->ti_Data;
break;
case TIA_Font:
FontAttr = (struct TextAttr *)Tag->ti_Data;
break;
case TIA_DrawInfo:
DrawInfo = (struct DrawInfo *)Tag->ti_Data;
break;
case TIA_SizeType:
SizeType = Tag->ti_Data;
break;
}
}
Count = 0;
if(Labels)
{
while(Labels[Count])
Count++;
}
if(DrawInfo && FontAttr && Labels && Count)
{
struct TextFont *Font;
if(Font = OpenFont(FontAttr))
{
struct RastPort RastPort,*RPort = &RastPort;
LONG i,Len,MaxWidth;
UWORD Lean,Thick;
InitRastPort(RPort);
SetFont(RPort,Font);
Box->Left = 0;
Box->Top = 0;
Box->Height = RPort->TxHeight + 11;
Lean = (TextLength(RPort,"A",1) + 1) / 2;
Thick = DrawInfo->dri_Resolution.Y / DrawInfo->dri_Resolution.X;
// Thick = 2;
if(Thick < 1)
Thick = 1;
for(i = MaxWidth = 0 ; i < Count ; i++)
{
if((Len = TextLength(RPort,Labels[i],strlen(Labels[i]))) > MaxWidth)
MaxWidth = Len;
}
MaxWidth = 2 + (Lean + Thick - 1 + Thick + MaxWidth + Thick + Lean + Thick - 1) + 2;
if(SizeType == GDOMAIN_MINIMUM && Count > 1)
Box->Width = 2 * Thick + MaxWidth + (Count - 1) * (Thick * 4) + Thick * 3;
else
Box->Width = 2 * Thick + Count * (MaxWidth + Thick) + Thick * 2;
CloseFont(Font);
Success = TRUE;
}
}
va_end(VarArgs);
return(Success);
}
ULONG __saveds __asm
LTP_TabClassDispatcher(register __a0 struct IClass *class,register __a2 Object *object,register __a1 Msg msg)
{
switch(msg->MethodID)
{
case OM_NEW:
return(NewMethod(class,(struct Gadget *)object,(struct opSet *)msg));
case OM_UPDATE:
case OM_SET:
return(SetMethod(class,(struct Gadget *)object,(struct opSet *)msg));
case OM_DISPOSE:
return(DisposeMethod(class,(struct Gadget *)object,msg));
case GM_RENDER:
return(RenderMethod(class,(struct Gadget *)object,(struct gpRender *)msg));
case GM_HITTEST:
return(GMR_GADGETHIT);
case GM_GOINACTIVE:
return(InactiveMethod(class,(struct Gadget *)object,(struct gpGoInactive *)msg));
case GM_HANDLEINPUT:
return(InputMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
case GM_GOACTIVE:
return(ActiveMethod(class,(struct Gadget *)object,(struct gpInput *)msg));
default:
return(DoSuperMethodA(class,object,msg));
}
}
#endif // defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)